package cn.qiyu5522.tk_ems.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.qiyu5522.tk_ems.entity.Classroom;
import cn.qiyu5522.tk_ems.entity.Department;
import cn.qiyu5522.tk_ems.entity.Major;
import cn.qiyu5522.tk_ems.entity.Student;
import cn.qiyu5522.tk_ems.entity.dto.ClassroomDTO;
import cn.qiyu5522.tk_ems.entity.dto.DepartmentAndMajorMenuDTO;
import cn.qiyu5522.tk_ems.entity.dto.QueryParamDTO;
import cn.qiyu5522.tk_ems.mapper.ClassroomMapper;
import cn.qiyu5522.tk_ems.mapper.StudentMapper;
import cn.qiyu5522.tk_ems.result.CustomMapResult;
import cn.qiyu5522.tk_ems.result.R;
import cn.qiyu5522.tk_ems.retrofit.IdGeneratorApi;
import cn.qiyu5522.tk_ems.service.ClassroomService;
import cn.qiyu5522.tk_ems.service.DepartmentService;
import cn.qiyu5522.tk_ems.service.MajorService;
import cn.qiyu5522.tk_ems.utils.RedisKey;
import cn.qiyu5522.tk_ems.utils.RedisUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Tonkey
 * @since 2023-02-07
 */
@Slf4j
@Service
public class ClassroomServiceImpl extends ServiceImpl<ClassroomMapper, Classroom> implements ClassroomService {

    @Resource
    private IdGeneratorApi idGeneratorApi;
    @Resource
    private StudentMapper studentMapper;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private DepartmentService departmentService;
    @Resource
    private MajorService majorService;
    @Resource
    private ObjectMapper objectMapper;

    @Override
    public R queryMajorByPageCondition(QueryParamDTO<ClassroomDTO> queryParamDTO) {
        ClassroomDTO condition = queryParamDTO.getCondition();
        IPage<Classroom> classroomPage = new Page<>(queryParamDTO.getCurrentPage(), queryParamDTO.getPageSize());
        LambdaQueryWrapper<Classroom> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(ObjectUtil.isNotEmpty(condition.getName()), Classroom::getName, condition.getName())
        .eq(ObjectUtil.isNotEmpty(condition.getMajorId()), Classroom::getMajorId, condition.getMajorId())
        .eq(ObjectUtil.isNotEmpty(condition.getDepartmentId()), Classroom::getDepartmentId, condition.getDepartmentId());
        baseMapper.selectPage(classroomPage, lambdaQueryWrapper);
        // 实体类转VO
        List<ClassroomDTO> classroomDTOS = objectMapper.convertValue(classroomPage.getRecords(), new TypeReference<List<ClassroomDTO>>() {
        });
        // 将院系编号、专业编号与其名称作映射
        List<Department> departments = departmentService.getForIdAndName();
        List<Major> majors = majorService.getForIdAndNameDepId();
        classroomDTOS.forEach(classroom -> {
            for (Department department : departments) {
                if(department.getId().equals(classroom.getDepartmentId())){
                    classroom.setDepartment(department.getName());
                }
            }
            for (Major major : majors) {
                if(major.getId().equals(classroom.getMajorId())){
                    classroom.setMajor(major.getName());
                }
            }
        });
        Map<String, Object> map = CustomMapResult.packagingResult(classroomDTOS, queryParamDTO.getCurrentPage(), queryParamDTO.getPageSize(), classroomPage.getTotal());
        return R.ok().data("classroomIPage", map);
    }

    @Override
    public R saveMore(List<ClassroomDTO> classroomDTOS) {
        // 待添加的班级信息集合
        List<Classroom> classroomList = new ArrayList<>(classroomDTOS.size());
        // 班级实体类对象
        Classroom classroom = null;
        for (ClassroomDTO classroomDTO : classroomDTOS) {
            // 对象转换将DTO类型转为实体类型
            classroom = new Classroom();
            BeanUtils.copyProperties(classroomDTO, classroom);
            // 班级编号由 院系编号加专业编号+0000组成
            String classroomIdPrefix = classroom.getDepartmentId() +""+ classroom.getMajorId();
            // 调用远程接口 生成班级编号
            Long classroomId = Long.valueOf(idGeneratorApi.getDefaultId(classroomIdPrefix));
            classroom.setId(classroomId);
            classroomList.add(classroom);
        }
        // 添加
        Integer integer = baseMapper.insertBatchSomeColumn(classroomList);
        // 添加成功，刷新Redis中的缓存
        if(integer>0){
            // 查询全部的院系数据
            QueryWrapper<Classroom> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id", "name","department_id","major_id");
            List<Classroom> classrooms = baseMapper.selectList(queryWrapper);
            redisUtil.set(RedisKey.CLASSROOM_ID_AND_NAME,classrooms,RedisKey.EXPIRE_ONE_DAY);
        }
        return integer.compareTo(0)>0? R.ok().message("专业添加成功"):R.error().message("专业添加失败");
    }

    @Override
    public R removeMore(List<Long> ids) {
        LambdaQueryWrapper<Student> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(Student::getClassroomId,ids);
        List<Student> students = studentMapper.selectList(lambdaQueryWrapper);
        if(CollectionUtil.isNotEmpty(students) ){
            return R.error().message("该班级下存在学生关联数据无法删除");
        }
        int i = baseMapper.deleteBatchIds(ids);
        if(i>0){
            // 更新Redis 里的值
            QueryWrapper<Classroom> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id", "name","department_id","major_id");
            List<Classroom> classrooms = baseMapper.selectList(queryWrapper);
            redisUtil.set(RedisKey.CLASSROOM_ID_AND_NAME, classrooms, RedisKey.EXPIRE_ONE_DAY);
        }
        return i>0?R.ok().message("班级删除成功"):R.error().message("班级删除失败");
    }

    @Override
    public List<Classroom> getForIdAndName() {
        List<Classroom> classrooms = new ArrayList<>();
        log.info("从Redis中拿取 班级编号与名称列表");
        classrooms = (List<Classroom>) redisUtil.get(RedisKey.CLASSROOM_ID_AND_NAME);
        if(CollectionUtil.isEmpty(classrooms)){
            log.info("Redis中无 班级编号与名称列表 ");
            QueryWrapper<Classroom> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id","name","major_id","department_id");
            classrooms = baseMapper.selectList(queryWrapper);
            if(classrooms.size()!=0){
                log.info("将 班级编号与名称列表 存入redis");
                redisUtil.set(RedisKey.CLASSROOM_ID_AND_NAME,classrooms,RedisKey.EXPIRE_ONE_DAY);
            }
        }
        return classrooms;

    }

    @Override
    public R getDepAndMaJor() {
        List<Department> departments = departmentService.getForIdAndName();
        List<Major> majors = majorService.getForIdAndNameDepId();
        // 实际返回的集合
        List<DepartmentAndMajorMenuDTO> menuDTOS = new ArrayList<>(departments.size());
        // 存放子节点
        List<DepartmentAndMajorMenuDTO> children_major = null;
        DepartmentAndMajorMenuDTO departmentNode = null;
        for (Department department : departments) {
            // 收集父节点信息
            departmentNode = new DepartmentAndMajorMenuDTO();
            departmentNode.setId(department.getId());
            departmentNode.setName(department.getName());
            departmentNode.setPid(0L);
            DepartmentAndMajorMenuDTO majorNode = null;
            children_major = new ArrayList<>();
            for (Major major : majors) {
                majorNode = new DepartmentAndMajorMenuDTO();
                if (department.getId().equals(major.getDepartmentId())) {
                    // 获取对应学院下的对应专业信息
                    majorNode.setId(major.getId());
                    majorNode.setName(major.getName());
                    majorNode.setPid(major.getDepartmentId());
                    if(CollectionUtil.isEmpty(majorNode.getChildren())){
                        majorNode.setChildren(null);
                    }
                    children_major.add(majorNode);
                }
            }
            // 父节点设置子集合
            departmentNode.setChildren(children_major);
            // 父节点存入集合中
            menuDTOS.add(departmentNode);
        }
        for (DepartmentAndMajorMenuDTO menuDTO : menuDTOS) {
            if(CollectionUtil.isEmpty(menuDTO.getChildren())){
                menuDTO.setChildren(null);
            }
        }
        return R.ok().data("depAndMajorMenu", menuDTOS);
    }


    @Override
    public R queryByName(String name) {
        QueryWrapper<Classroom> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(name),"name",name);
        List<Classroom> classrooms = baseMapper.selectList(queryWrapper);
        return classrooms.size()==0?
                R.ok().message("名称可用").data("flag",true):
                R.ok().message("名称不可用").data("flag",false);
    }




}
